/*
 * XMLAdaptor.java
 *
 * Created Oct 10, 2006
 * David Connell
 * Copyright (c) 2005 Synergy Systems, Inc
 */
package org.puresilk.afx.adaptable;

import java.net.URL;
import java.net.URLConnection;
import java.util.logging.Logger;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.transform.XSLTransformException;
import org.jdom.transform.XSLTransformer;

import org.puresilk.afx.interfaces.SilkXMLBean;

/**
 * XML Adaptor that uses XSLT to transform 
 * inputs and outputs.
 * 
 * The default implementation requires the full 
 * URLs when specifying the stylesheets and the 
 * resulting transformations must set up the 
 * resulting part as the root element.
 */
public class XMLAdaptor extends Adaptable {
	private static Logger logger = Logger.getLogger(XMLAdaptor.class.getName());
	private XSLTransformer xsltIn = null;
	private XSLTransformer xsltOut = null;

	/** one shot constructor */ 
	public XMLAdaptor(SilkXMLBean bean, String xIn, String xOut){
		setBean(bean);
		setXsltOut(xOut);
		setXsltIn(xIn);
	}
	
	/** set input stylesheet */
	public void setXsltIn(String xIn) {
		this.xsltIn = getXSLT(xIn);
	}

	/** set output stylesheet */
	public void setXsltOut(String xOut) {
		this.xsltOut = getXSLT(xOut);
	}
	
	/**
	 * Set internal attributes from
	 * external xml with optional
	 * XSLT Transformation prior to
	 * updates..
	 */
	public void from_xml(Element xml) {
		Element el = xml;
		try{
			if((xsltIn != null) && (el != null)) {
				// transforms are doc to doc
				Document doc = new Document(xml);
		
				// retrieve root element
				el = xsltIn.transform(doc).getRootElement();
			}
		}
		catch(XSLTransformException ex){
			logger.throwing("XMLAdaptor", "from_xml", ex);
		}

		
		// if we have a node, use it
		if(el != null)
			super.from_xml(el);
	}
	
	/**
	 * Export internal attributes to
	 * an external xml with optional
	 * formatting via XSLT.
	 */
	public Element to_xml() {
		// set up defaults
		Element xml = super.to_xml();
		Element el = xml;

		try{
			// process if everything is good
			if((xsltOut != null) && (xml != null)) {
				// transforms are doc to doc
				Document doc = new Document(xml);
	
				// retrieve root element
				el = xsltOut.transform(doc).getRootElement();
			}
		}
		catch(XSLTransformException ex){
			logger.throwing("XMLAdaptor", "from_xml", ex);
		}

		// return results
		return el;
	}

	/**
	 * Load up an XSLT Processor with a style sheet from the
	 * web space.
	 *  
	 * @param path
	 * @return
	 */
	protected XSLTransformer getXSLT(String urlPath){
		XSLTransformer xslt = null;
		try {
			// get the url for the stylesheet
			URL url = new URL(urlPath);
			URLConnection conn = url.openConnection();
			
			// build from stream
			xslt = new XSLTransformer(conn.getInputStream());
		}
		catch(Exception ex) {
			// log it and set for null result
			xslt = null;
		}
		
		// return transformer
		return xslt;
	}
}
